package org.budo.support.jsqlparser;

import java.util.List;

import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.delete.Delete;
import net.sf.jsqlparser.statement.insert.Insert;
import net.sf.jsqlparser.statement.select.OrderByElement;
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.Select;
import net.sf.jsqlparser.statement.select.SelectBody;
import net.sf.jsqlparser.statement.update.Update;

/**
 * @author limingwei
 */
@Slf4j
public class JSqlParserUtil {
    public static List<OrderByElement> getOrderByElements(String orderBySql) {
        if (null == orderBySql || orderBySql.trim().isEmpty()) {
            log.error("#25 getOrderByElements null, orderBySql = " + orderBySql);
            return null;
        }

        if (orderBySql.trim().startsWith("index ")) {
            orderBySql = orderBySql.replace("index ", "`index` ");
        } else {
            orderBySql = orderBySql.replace(" index ", " `index` ");
        }

        Statement statement = JSqlParserUtil.parse("SELECT * FROM t_orderByFieldNameToColumn ORDER BY " + orderBySql);
        if (!(statement instanceof Select)) {
            log.error("#31 getOrderByElements not Select, orderBySql = " + orderBySql);
            return null;
        }

        Select select = (Select) statement;
        SelectBody selectBody = select.getSelectBody();
        if (null == selectBody || !(selectBody instanceof PlainSelect)) {
            log.error("#38 selectBody = " + selectBody + ", orderBySql=" + orderBySql);
            return null;
        }

        PlainSelect plainSelect = (PlainSelect) selectBody;
        return plainSelect.getOrderByElements();
    }

    public static Statement parse(String sql) {
        try {
            return CCJSqlParserUtil.parse(sql);
        } catch (JSQLParserException e) {
            throw new RuntimeException("#15 sql=" + sql + ", e=" + e, e);
        }
    }

    /**
     * 去掉反引号
     */
    protected static String removeBackquote(String name) {
        if (null == name) {
            return name;
        }

        if (name.startsWith("`")) {
            name = name.substring(1);
        }

        if (name.endsWith("`")) {
            name = name.substring(0, name.length() - 1);
        }

        return name;
    }

    public static String getTableName(Statement statement) {
        if (null == statement) {
            return null;
        }

        if (statement instanceof Select) {
            PlainSelect plainSelect = (PlainSelect) ((Select) statement).getSelectBody();
            Table table = (Table) plainSelect.getFromItem();
            if (null == table) {
                return null;
            }

            String tableName = table.getName();
            return removeBackquote(tableName);
        }

        if (statement instanceof Insert) {
            return removeBackquote(((Insert) statement).getTable().getName());
        }

        if (statement instanceof Update) {
            return removeBackquote(((Update) statement).getTables().get(0).getName());
        }

        if (statement instanceof Delete) {
            return removeBackquote(((Delete) statement).getTable().getName());
        }

        throw new RuntimeException("#29 statement=" + statement + ", type=" + statement.getClass());
    }
}